package xyz.ddlnt.servicemg.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xyz.ddlnt.commonutil.constant.FieldConstants;
import xyz.ddlnt.commonutil.enumeration.ResultCode;
import xyz.ddlnt.commonutil.exception.GlobalException;
import xyz.ddlnt.commonutil.util.RandomUtil;
import xyz.ddlnt.model.dto.ExamQuestionDTO;
import xyz.ddlnt.model.dto.PublishStatus;
import xyz.ddlnt.model.entity.ExamQuestion;
import xyz.ddlnt.model.vo.ExamQuestionInfoVO;
import xyz.ddlnt.model.vo.ExamQuestionVO;
import xyz.ddlnt.servicemg.mapper.ExamQuestionMapper;
import xyz.ddlnt.servicemg.service.ExamQuestionService;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author ZZULI_SE 210910
 * @data 2025/5/3 21:47
 */
@Slf4j
@Service
public class ExamQuestionServiceImpl extends ServiceImpl<ExamQuestionMapper, ExamQuestion> implements ExamQuestionService {

    @Resource
    private ExamQuestionMapper examQuestionMapper;

    @Override
    public ExamQuestionVO addExamQuestion(ExamQuestionDTO examQuestionDTO) {
        Long id = RandomUtil.generate12DigitRandomNumber();
        String jsonString = null;
        if ( examQuestionDTO.getExamQuesDir() != null && !examQuestionDTO.getExamQuesDir().isEmpty() ) {
            jsonString = examQuestionDTO.getExamQuesDir().toJSONString();
        }
        LocalDateTime now = LocalDateTime.now();
        ExamQuestion examQuestion = ExamQuestion.builder()
                .id(id)
                .categoryId(examQuestionDTO.getCategoryId())
                .technologyId(examQuestionDTO.getTechnologyId())
                .questionTitle(examQuestionDTO.getQuestionTitle())
                .examQuesDir(jsonString)
                .questionContent(examQuestionDTO.getQuestionContent())
                .publishStatus(FieldConstants.NOT_PUBLISHED)
                .publishTime(now)
                .updateTime(now)
                .build();
        try {
            examQuestionMapper.insert(examQuestion);
        }catch (DuplicateKeyException e) {
            throw new GlobalException(ResultCode.NAME_ALREADY_EXISTS);
        }catch (Exception e) {
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        ExamQuestionVO examQuestionVO = new ExamQuestionVO();
        BeanUtils.copyProperties(examQuestion, examQuestionVO);
        return examQuestionVO;
    }

    @Override
    @Transactional // TODO Seata 分布式事务
    public Boolean deleteById(Long id) {
        // 删除试题信息
        try {
            examQuestionMapper.deleteById(id);
        }catch (Exception e) {
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }

        // 删除试题信息下的浏览记录

        // 删除试题信息下的收藏记录

        // 删除试题信息下的点赞记录

        return true;
    }

    @Override
    public ExamQuestionVO updateExamQuestion(ExamQuestionDTO examQuestionDTO) {
        String jsonString = examQuestionDTO.getExamQuesDir().toJSONString();
        LocalDateTime now = LocalDateTime.now();
        LambdaUpdateWrapper<ExamQuestion> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .set(!StringUtils.isEmpty(examQuestionDTO.getQuestionTitle()), ExamQuestion::getQuestionTitle, examQuestionDTO.getQuestionTitle())
                .set(!StringUtils.isEmpty(jsonString), ExamQuestion::getExamQuesDir, jsonString)
                .set(!StringUtils.isEmpty(examQuestionDTO.getQuestionContent()), ExamQuestion::getQuestionContent, examQuestionDTO.getQuestionContent())
                .set(ExamQuestion::getUpdateTime, now)
                .eq(ExamQuestion::getId, examQuestionDTO.getId());
        try {
            examQuestionMapper.update( updateWrapper);
        }catch (Exception e) {
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        return ExamQuestionVO.builder()
                .id(examQuestionDTO.getId())
                .questionTitle(examQuestionDTO.getQuestionTitle())
                .updateTime(now)
                .build();
    }

    @Override
    public ExamQuestionInfoVO getExamQuestionById(Long id) {
        LambdaQueryWrapper<ExamQuestion> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExamQuestion::getId, id)
                .select(ExamQuestion::getQuestionTitle, ExamQuestion::getExamQuesDir, ExamQuestion::getQuestionContent,
                        ExamQuestion::getViewCount, ExamQuestion::getLikeCount, ExamQuestion::getCollectCount, ExamQuestion::getPublishStatus);
        ExamQuestion examQuestion = examQuestionMapper.selectOne(queryWrapper);
        ExamQuestionInfoVO examQuestionVO = ExamQuestionInfoVO.builder().id(id).build();
        BeanUtils.copyProperties(examQuestion, examQuestionVO);
        examQuestionVO.setExamQuesDir(JSONArray.parseArray(examQuestion.getExamQuesDir()));
        return examQuestionVO;
    }

    @Override
    public List<ExamQuestionVO> listExamQuestionVO() {
        return examQuestionMapper.queryExamQuestionVOS();
    }

    @Override
    public Boolean updatePublishStatus(PublishStatus publishStatus) {
        LambdaUpdateWrapper<ExamQuestion> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ExamQuestion::getPublishStatus, publishStatus.getPublishStatus())
                .eq(ExamQuestion::getId, publishStatus.getId());
        try {
            examQuestionMapper.update(updateWrapper);
        }catch (Exception e) {
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        return true;
    }
}
